package com.tuocent.dagv2.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuocent.dagv2.common.AjaxResult;
import com.tuocent.dagv2.common.entity.LoginUserInfo;
import com.tuocent.dagv2.common.entity.Transfer;
import com.tuocent.dagv2.common.utils.SnowFlakeID;
import com.tuocent.dagv2.common.utils.redis.RedisCache;
import com.tuocent.dagv2.constant.PublicConst;
import com.tuocent.dagv2.entity.*;
import com.tuocent.dagv2.mapper.ArchivesClassifyMapper;
import com.tuocent.dagv2.mapper.TaskMapper;
import com.tuocent.dagv2.service.IProjectsService;
import com.tuocent.dagv2.service.ITaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tuocent.dagv2.service.IUserPermissionService;
import com.tuocent.dagv2.service.IUsersService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.ui.Model;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 任务管理 服务实现类
 * </p>
 *
 * @author Vincent
 * @since 2025-07-22
 */
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements ITaskService {
    @Resource
    private SnowFlakeID snowFlakeID;
    @Resource
    private RedisCache redis;

    @Autowired
    private IProjectsService projectsService;
    @Autowired
    private ArchivesClassifyMapper archivesClassifyMapper;
    @Autowired
    private IUserPermissionService userPermissionService;

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private IUsersService usersService;

    @Override
    public String taskInfo(Model model) {
        List<Projects> projectsList = projectsService.list(new QueryWrapper<Projects>()
                .select("id", "name")
                .eq("is_del", "0"));
        model.addAttribute("projectsList", projectsList);
        return "/project/taskInfo";
    }

    @Override
    public AjaxResult getTaskInfo(String pid, Integer page, Integer limit) {
        Page<Task> data = page(new Page<>(page, limit), new QueryWrapper<Task>()
                .eq("pid", pid).eq("is_del", "0"));
        return AjaxResult.success(data.getRecords(), data.getTotal());
    }

    @Override
    public String setTaskInfo(Model model, String id, String pid) {
        Task data = getOne(new QueryWrapper<Task>().eq("id", id).eq("pid", pid));
        if (data == null) {
            data = new Task();
            data.setPid(pid);
            data.setTaskModel("1");
        }
        List<ArchivesClassify> classifyList = archivesClassifyMapper.selectList(new QueryWrapper<ArchivesClassify>().eq("isdel", "0"));
        model.addAttribute("classifyList", classifyList);
        model.addAttribute("data", data);
        return "/project/setTaskInfo";
    }

    @Override
    public AjaxResult saveTaskInfo(HttpSession session, Task data) {
        LoginUserInfo loginUserInfo = redis.get(session.getId());
        if (data == null) {
            return AjaxResult.error("没有可保存的数据");
        }
        ArchivesClassify classify = archivesClassifyMapper.selectById(data.getArchivesClassifyId());
        if (classify == null) {
            return AjaxResult.error("没有找到该任务对应的档案门类");
        }
        data.setFillingModel(classify.getFillingModel());
        if (data.getId() == null || data.getId().isEmpty()) {
            data.setId(snowFlakeID.getId());
            data.setIsDel("0");
            data.setStatus("0");
            data.setIsStart("0");
            data.setCreator(loginUserInfo.getUserName());
            data.setCreateTime(LocalDateTime.now());
        } else {
            data.setUpdater(loginUserInfo.getUserName());
            data.setUpdateTime(LocalDateTime.now());
        }

        QueryWrapper<Task> queryWrapper = new QueryWrapper<Task>()
                .eq("pid", data.getPid())
                .eq("task_name", data.getTaskName())
                .eq("is_del", "0")
                .ne("id", data.getId());
        if (count(queryWrapper) > 0L) {
            return AjaxResult.error("该任务已存在");
        }
        return saveOrUpdate(data) ? AjaxResult.success("保存任务成功") : AjaxResult.error("保存任务失败");
    }

    @Override
    public AjaxResult delTaskInfo(String id) {
        UpdateWrapper<Task> uw = new UpdateWrapper<Task>().set("is_del", "1").eq("id", id);
        return update(uw) ? AjaxResult.success("删除任务成功") : AjaxResult.error("删除任务失败");
    }

    @Override
    public String setTaskStart(Model model, String id) {
        model.addAttribute("id", id);
        model.addAttribute("startDate", LocalDate.now());
        return "/project/setTaskStart";
    }

    @Override
    public AjaxResult taskStart(Map<String, Object> data) {
        String id = data.containsKey("id") ? data.get("id").toString() : "";
        LocalDate startDate = data.containsKey("startDate") ? LocalDate.parse(data.get("startDate").toString(), PublicConst.dateFormat) : LocalDate.now();
        Task task = getById(id);
        if (task == null) {
            return AjaxResult.error("没有需要启动的任务");
        }
        Projects projects = projectsService.getById(task.getPid());
        if (projects == null) {
            return AjaxResult.error("没有找到该任务的项目信息");
        }
        if (!"1".equals(projects.getStatus())) {
            return AjaxResult.error("该任务的项目不在启动状态，请先启动项目");
        }
        if (!"0".equals(task.getStatus()) && !"1".equals(task.getStatus())) {
            return AjaxResult.error("该任务不在可启动状态");
        }
        task.setStatus("1");
        task.setIsStart("1");
        task.setStartDate(startDate);
        return updateById(task) ? AjaxResult.success("任务启动成功") : AjaxResult.error("任务启动失败");
    }

    @Override
    public AjaxResult taskFinish(Map<String, Object> data) {
        String id = data.containsKey("id") ? data.get("id").toString() : "";
        LocalDate edate = data.containsKey("edate") ? LocalDate.parse(data.get("edate").toString(), PublicConst.dateFormat) : LocalDate.now();
        Task task = getById(id);
        if (task == null) {
            return AjaxResult.error("没有需要结束的任务");
        }
        if (!"1".equals(task.getStatus())) {
            return AjaxResult.error("该任务不在可结束的状态");
        }
        if (edate.isBefore(task.getStartDate())) {
            return AjaxResult.error("任务完成日期不可小于项目启动日期");
        }
        task.setStatus("2");
        task.setEndDate(edate);
        return updateById(task) ? AjaxResult.success("任务成功设置为结束") : AjaxResult.error("任务设置为结束失败");
    }

    @Override
    public String setUserTask(Model model, String userId) {
        Users user = usersService.getOne(new QueryWrapper<Users>()
                .eq("id", userId)
                .eq("is_del", "0"));
        if (user == null) {
            model.addAttribute("message", "没找到该用户信息");
            return "/home/error";
        }
        if (user.getIsSys().equals("1")) {
            model.addAttribute("message", "该用户为系统用户，不可设置此功能");
            return "/home/error";
        }
        model.addAttribute("userId", userId);
        List<Projects> projectsList = projectsService.list(new QueryWrapper<Projects>().eq("is_del", "0"));
        model.addAttribute("projectsList", projectsList);
        return "/project/setUserTask";
    }

    @Override
    public AjaxResult getUserTask(String pid, String userId) {
        List<Task> tasks = list(new QueryWrapper<Task>()
                .eq("pid", pid)
                .eq("is_del", "0")
                .orderByAsc("id"));
        List<UserPermission> userPermissions = userPermissionService.list(new QueryWrapper<UserPermission>()
                .eq("pid", pid)
                .eq("userid", userId));
        List<Transfer> transfers = new ArrayList<>();
        List<String> values = new ArrayList<>();
        for (Task task : tasks) {
            Transfer transfer = new Transfer();
            transfer.setValue(task.getId());
            transfer.setTitle(task.getTaskName());
            transfer.setChecked("");
            transfer.setDisabled("");
            transfers.add(transfer);
        }
        for (UserPermission userPermission : userPermissions) {
            values.add(userPermission.getKeyid());
        }
        List<Object> data = new ArrayList<>();
        data.add(transfers);
        data.add(values);
        return AjaxResult.success(data);
    }

    @Override
    public AjaxResult getUserProjectTask(String pid, String userId) {
        List<Task> tasks = list(new QueryWrapper<Task>()
                .eq("pid", pid)
                .eq("is_del", "0")
                .orderByAsc("id"));
        List<UserPermission> userPermissions = userPermissionService.list(new QueryWrapper<UserPermission>()
                .eq("pid", pid)
                .eq("userid", userId));
        List<Transfer> transfers = new ArrayList<>();
        for (Task task : tasks) {
            for (UserPermission userPermission : userPermissions) {
                if (task.getId().equals(userPermission.getKeyid())) {
                    Transfer transfer = new Transfer();
                    transfer.setValue(task.getId());
                    transfer.setTitle(task.getTaskName());
                    transfer.setChecked("");
                    transfer.setDisabled("");
                    transfers.add(transfer);
                }
            }

        }
        return AjaxResult.success(transfers);
    }

    @Override
    public AjaxResult saveUserTask(JSONObject data) {
        String pid = data.containsKey("pid") ? data.get("pid").toString() : "";
        String userId = data.containsKey("userId") ? data.get("userId").toString() : "";
        String action = data.containsKey("action") ? data.get("action").toString() : "0";
        JSONArray dataArray = data.getJSONArray("data");
        List<Transfer> transfers = JSON.parseArray(dataArray.toJSONString(), Transfer.class);

        DataSourceTransactionManager tran = new DataSourceTransactionManager(jdbcTemplate.getDataSource());
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus update = tran.getTransaction(def);

        switch (action) {
            case "0":
                for (Transfer transfer : transfers) {
                    if (userPermissionService.count(new QueryWrapper<UserPermission>()
                            .eq("pid", pid)
                            .eq("userId", userId)
                            .eq("keyid", transfer.getValue())) == 0) {
                        UserPermission work = new UserPermission();
                        work.setId(snowFlakeID.getId());
                        work.setPid(pid);
                        work.setUserid(userId);
                        work.setKeyid(transfer.getValue());
                        work.setModel(11);
                        work.setIsuse("1");
                        userPermissionService.save(work);
                    }
                }
                break;
            case "1":
                for (Transfer transfer : transfers) {
                    userPermissionService.remove(new QueryWrapper<UserPermission>()
                            .eq("pid", pid)
                            .eq("userid", userId)
                            .eq("keyid", transfer.getValue())
                            .eq("model", 11));
                }
                break;
        }
        try {
            tran.commit(update);
            return AjaxResult.success("设置任务成功");
        } catch (Exception e) {
            tran.rollback(update);
            return AjaxResult.error("设置任务失败，错误信息：" + e.getMessage());
        }
    }

    @Override
    public String setTaskFinish(Model model, String id) {
        model.addAttribute("id", id);
        model.addAttribute("edate", LocalDate.now());
        return "/project/setTaskFinish";
    }

    @Override
    public AjaxResult getUserTaskInfo(HttpSession session, String pid, Integer page, Integer limit) {
        LoginUserInfo loginUser = redis.get(session.getId());
        if (loginUser == null) {
            return AjaxResult.error("没有找到登录用户信息，请重新登录");
        }
        List<Task> data = getBaseMapper().userTask(loginUser.getUserId(), pid);
        return AjaxResult.success(data);
    }

    @Override
    public Task getTask(String pid, String tid) {
        return getOne(new QueryWrapper<Task>().eq("pid", pid).eq("id", tid).last("limit 1"));
    }


}
